#ifndef   _OVMF_HASH_TABLE_H
#define  _OVMF_HASH_TABLE_H

#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-" \
                 "%02hhx%02hhx-%02hhx%02hhx-" \
                 "%02hhx%02hhx-" \
                 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"

typedef struct __attribute__((packed)) reset_info_block_t{
    /* Reset Vector Address */
    uint32_t reset_addr;
} reset_info_block;


typedef struct __attribute__((packed)) hash_table_descriptor_t {
    /* hash table area guest address */
    uint32_t base;
    /* hash table area size (in bytes) */
    uint32_t size;
} hash_table_descriptor;


typedef struct uuid_structure_t{
   union {
        unsigned char data[16];
        struct {
            /* Generated in BE endian, can be swapped with qemu_uuid_bswap. */
            uint32_t time_low;
            uint16_t time_mid;
            uint16_t time_high_and_version;
            uint8_t  clock_seq_and_reserved;
            uint8_t  clock_seq_low;
            uint8_t  node[6];
        } fields;
    };
} uuid;


/* sha256 digest size */
#define HASH_SIZE 32
typedef struct __attribute__((packed)) hash_table_entry_t {
    uuid     guid;
    uint16_t len;
    uint8_t  hash[HASH_SIZE];
} hash_table_entry;

typedef struct __attribute__((packed)) hash_table_t {
    uuid              guid;
    uint16_t          len;
    hash_table_entry  cmdline;
    hash_table_entry  initrd;
    hash_table_entry  kernel;
    uint8_t padding[];
} hash_table;

#define HASH_TABLE_GUID         "7255371f-3a3b-4b04-927b-1da6efa8d454"

#define RESET_BLOCK_GUID        "00f771de-1a7e-4fcb-890e-68c77e2fb44e"

#define HASH_TABLE_HEADER_GUID  "9438d606-4f22-4cc9-b479-a793d411fd21"

#define KERNEL_ENTRY_GUID       "4de79437-abd2-427f-b835-d5b172d2045b"

#define INITRD_ENTRY_GUID       "44baf731-3a2f-4bd7-9af1-41e29169781d"

#define CMDLINE_ENTRY_GUID      "97d02dd8-bd20-4c94-aa78-e7714d36ab2a"

#define OVMF_TABLE_FOOTER_GUID  "96b582de-1fb2-45f7-baea-a366c55a082d"


int ovmf_find_hash_table_desc(uint8_t *ovmf, uint32_t ovmf_size, uint32_t *addr);
int fill_csv_hash_table(hash_table *ht, char *kernel_file, char *cmdline, char *initrd_file);
int ovmf_find_reset_vector(uint8_t *ovmf, size_t ovmf_size, uint32_t *addr);

#endif
